package service

import (
	"github.com/sirupsen/logrus"
	"math/rand"
	"morleyStoneHome/dao"
	"morleyStoneHome/model"
	"morleyStoneHome/util"
	"strconv"
	"time"
)

type catcoinService struct{}

var CatcoinService = newCatcoinService()

func newCatcoinService() *catcoinService {
	return &catcoinService{}
}

//参与活动接口，可选参数：邀请码，有则接受邀请//2021.8.2:取消校验
func (c *catcoinService) Insert(addr string, invcode int) (msg string, err error) {
	//先校验地址是否在wallet_device_uid表里存在//2021.8.2:取消校验
	//one, err := dao.WalletDeviceUidDao.FindOne(addr)
	//if err != nil {
	//	logrus.Error(err)
	//	return "地址校验失败", err
	//}
	//if len(one) == 0 {
	//	return "该地址不存在或不是ERC20", util.NewError(1, "该地址不存在或不是ERC20")
	//}
	//oneStr := util.JsonData(one)
	//if -1 == strings.Index(oneStr, "ERC20") {
	//	return "not ERC", util.NewError(1,"not ERC20") //如果不是ERC20
	//}
	//校验catcoin表里是否存在，如果已存在，直接返回
	cats, err := dao.CatcoinDao.FindOne(addr)
	if nil != err {
		logrus.Error(err)
		return "校验失败", err
	}
	if len(cats) != 0 {
		return "该地址已参与过活动", util.NewError(1, "该地址已参与过活动")
	}
	//校验通过，判断邀请人invcode是否存在
	inv, err := dao.CatcoinDao.FindOneByInv(invcode)
	if err != nil {
		logrus.Error(err)
		return "邀请码不存在", err
	}
	var catcoin = newCat(addr, inv) //实例化一个新的被邀请进来的cat
	err = dao.CatcoinDao.Insert(catcoin)
	if nil != err {
		logrus.Error(err)
		return "参与活动失败，请稍后重试", err
	}
	if len(inv) != 0 { //非空说明有邀请人，以下需要更新邀请人，邀请人数+1
		addr, cat := newInvCat(inv)
		err = dao.CatcoinDao.Update(addr, cat)
		if nil != err {
			logrus.Error(err)
			return "更新邀请人信息失败", err
		}
	}
	return "success", nil
}

//查询用户的推广奖励，包括提现列表，允许还未质押，未推广，未提现，如此则返回空值
func (c *catcoinService) FindOne(addr string) (res *model.StoRewardVO, err error) {
	var cat *model.Catcoin
	cats, err := dao.CatcoinDao.FindOne(addr)
	if nil != err {
		logrus.Error(err)
		return nil, err
	}
	if len(cats) == 0 {
		return nil, nil
	} else {
		cat = &cats[0]
	}
	stos, err := dao.StoRewardDao.FindOne(cat.Uid)
	if nil != err {
		logrus.Error(err)
		return nil, err
	}
	var sto *model.StoReward
	if 0 == len(stos) {
		sto = nil
	} else {
		sto = &stos[0]
	}
	list, err := dao.StoWithdrawDao.FindList(addr)
	if nil != err {
		logrus.Error(err)
		return nil, err
	}
	vo := model.NewStoRewardVo(cat, sto, list)
	return vo, err
}

//查询直推情况(是直推列表，不含提现列表)
func (c *catcoinService) FindFollowers(addr string) (fflist []*model.StoRewardVO, err error) {
	one, err := dao.CatcoinDao.FindOne(addr)
	if nil != err {
		logrus.Error(err)
		return nil, err
	}
	var list []model.Catcoin
	if len(one) != 0 {
		logrus.Info("catcoin service :: dao.CatcoinDao.FindFollowerList(marketer.Uid) ==> ", one[0].Uid)
		list, err = dao.CatcoinDao.FindFollowerList(one[0].Uid)
	} else {
		return nil, nil
	}
	if nil != err {
		logrus.Error(err)
		return nil, err
	}
	for i := 0; i < len(list); i++ {
		logrus.Info("catcoin service :: dao.StoRewardDao.FindOne(one of followers.Uid) ==> ", list[i].Uid)
		sto, err := dao.StoRewardDao.FindOne(list[i].Uid)
		var s *model.StoReward
		if nil != err {
			logrus.Error(err)
			return nil, err
		} else if 0 != len(sto) {
			s = &sto[0]
		}
		logrus.Info("catcoin service :: find follower : ", &list[i], ";  follower's sto : ", s)
		fflist = append(fflist, model.NewStoRewardVo(&list[i], s, nil))
	}
	return fflist, nil
}

//有无邀请人inv都可用此方法实例化被邀请人,首次插入表中数据
func newCat(addr string, inv []model.Catcoin) *model.CatcoinDto {
	var cat *model.CatcoinDto
	var invcat model.Catcoin
	if len(inv) == 0 { //说明无邀请人
		cat = &model.CatcoinDto{
			0, //自增的，值多少无所谓
			addr,
			generateInvCode(),
			0,
			0,
			"0,",
			time.Now(),
			time.Now(),
			0,
		}
	} else { //有邀请人
		invcat = inv[0] //邀请人
		puidstr := invcat.Puids + strconv.Itoa(invcat.Uid) + ","
		cat = &model.CatcoinDto{
			0,
			addr,
			generateInvCode(),
			0,
			invcat.Uid,
			puidstr,
			time.Now(),
			time.Now(),
			0,
		}
	}

	return cat
}

func newInvCat(inv []model.Catcoin) (addr string, cat *model.Catcoin) {
	catcoin := inv[0]
	addr = catcoin.Addr
	cat = &model.Catcoin{
		catcoin.Uid,
		catcoin.Addr,
		catcoin.InvCode,
		catcoin.InvCount + 1,
		catcoin.Puid,
		catcoin.Puids,
		catcoin.Ctime,
		time.Now(),
		catcoin.Pledged,
	}
	return addr, cat
}

func generateInvCode() int {
	for {
		//生成8位随机数
		//到数据库中查询是否存在，如果不存在，返回，如果存在，重新生成，直到查询不存在
		rand.Seed(time.Now().Unix())
		r := rand.New(rand.NewSource(time.Now().UnixNano()))
		i := int(r.Float64() * 10000000)
		inv, err := dao.CatcoinDao.FindOneByInv(i)
		if nil != err {
			logrus.Error(err)
		}
		if len(inv) == 0 && i > 99999 { //确保至少是6位数的yaoqing码
			return i
		}
	}
}
